package model.doe;

public class FocusatorSquareShape extends AbstractDoe {

	private double rad;
	private double f;
	private double d;
	private double wl;
	private double angle;
	private double doeStep;
	private boolean addLen;
	private double min;
	private double cos;

	public FocusatorSquareShape(double rad, double f, double d, double wl, double angle, double doeStep, boolean addLen) {
		this.rad = rad;
		this.f = f;
		this.d = d;
		this.wl = wl;
		this.angle = angle;
		this.doeStep = doeStep;
		this.addLen = addLen;

		this.cos = Math.cos(angle * Math.PI / 180);
		this.wl = wl / 1000;
		
		super.widthPointsNumber = (int) (2*rad / doeStep);
		super.heightPointsNumber = (int) (2*rad / doeStep);
		
		contourMinMax();
		
		
	}
	
	private double calculate (double u, double v){
		if (Math.sqrt(u * cos * u * cos + v * v) > rad)
			return 0;
		return contourFun(u, v);
	}

	

	private void contourMinMax() {

		if (!addLen) {
			super.minValue = Math.PI / 4;
			super.maximumValue = 7 * (min);
		}

		else {
			super.minValue = -Math.PI * rad * rad / (wl * f) + Math.PI / 4;
			super.maximumValue = 7 * Math.PI / 4;
		}
	}
	
	private double contourFun(double ul, double vl) {
	    
	    
	    
	    double c, ph, ph1, rez=0;
	    
	    int id, id1;
	    
	    
	    
	    c = 2*Math.PI/(wl*f);
	    
	    if( Math.sqrt(ul*ul+vl*vl) <= rad)
	        
	    {
	        
	        ph =(c*.75*d/Math.pow(rad,3))*(.5*Math.pow(vl*rad,2)-Math.pow(vl,4)/12);
	        
	        ph1=(c*.75*d/Math.pow(rad,3))*(.5*Math.pow(ul*rad,2)-Math.pow(ul,4)/12);
	        
	        ph  +=c*(ul+rad)*d/2;
	        
	        ph1 +=c*(vl+rad)*d/2;
	        
	        ph   =(ph%2*Math.PI);
	        
	        ph1  =(ph1%2*Math.PI);
	        
	        if( ph <Math.PI ) id =1; else id =2;
	        
	        if( ph1<Math.PI ) id1=3; else id1=4;
	        
	        if( (id==1) && (id1==3) ) rez= 7*Math.PI/4;
	        
	        if( (id==1) && (id1==4) ) rez=   Math.PI/4;
	        
	        if( (id==2) && (id1==3) ) rez= 5*Math.PI/4;
	        
	        if( (id==2) && (id1==4) ) rez= 3*Math.PI/4;
	        
	        
	        
	    }
	    
	    else  rez = 0;
	    
	    if(!addLen) return rez;
	    
	    else     return (rez-c*(ul*ul+vl*vl)/2);    
	    
	}

	@Override
	public double run(int i, int j) {
		
		return calculate(doeStep * i, doeStep * j);
	}
}
